/**
 * 图层数据类型
 */
export interface Layer {
  id: string
  name: string
  visible?: boolean
  opacity?: number
  icon?: string
  layers?: Layer[]
}

export class LayerManager {
  private readonly _id: string

  private readonly _map

  private readonly _layers: Layer[]

  private readonly _eventListener: Map<string, Function[]>

  constructor(id: string, map: any) {
    this._id = id
    this._map = map
    this._layers = []
    this._eventListener = new Map()
  }

  get layers() {
    return this._layers
  }

  on(type: string, callback: Function) {
    if (this._eventListener.has(type)) {
      this._eventListener.get(type)?.push(callback)
    } else {
      this._eventListener.set(type, [callback])
    }
  }

  off(type: string, callback?: Function) {
    if (this._eventListener.has(type)) {
      if (callback) {
        const functionList = this._eventListener.get(type)
        if (functionList) {
          const index = functionList.findIndex((item) => item === callback)
          if (index !== -1) {
            functionList.splice(index, 1)
          }
        }
      } else {
        this._eventListener.delete(type)
      }
    }
  }

  fire(type: string, params: any) {
    if (this._eventListener.has(type)) {
      this._eventListener.get(type)?.forEach((fn) => {
        fn(params)
      })
    }
  }

  /**
   * 添加图层
   *
   * @param {string} id 图层id
   *
   * @param {string} name 图层名称
   *
   * @param {boolean} [visible=true] 图层显隐
   *
   * @param {number} [opacity=1] 图层不透明度
   *
   * @param {Layer[]} [layers] 包含子图层
   */
  addLayer(
    id: string,
    name: string,
    visible: boolean = true,
    opacity: number = 1,
    layers?: Layer[]
  ) {
    const data: Layer = {
      id: id,
      name: name,
      visible: visible,
      opacity: opacity,
      layers: layers,
    }
    this._layers.push(data)
    this.fire('add', data)
  }

  /**
   * 移除图层
   *
   * @param {string} id 图层id
   *
   * @return {boolean} 是否移除成功
   */
  removeLayer(id: string): boolean {
    const index = this._layers.findIndex((layer) => layer.id === id)
    if (index === -1) {
      return false
    } else {
      this._layers.splice(index, 1)
      this.fire('remove', id)
      return true
    }
  }
}
